package com.xiaobaibai.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaobaibai.bo.ProductEs;
import com.xiaobaibai.common.EsCommon;
import com.xiaobaibai.common.IndexCommon;
import com.xiaobaibai.common.OrderCommon;
import com.xiaobaibai.dao.ProductDao;
import com.xiaobaibai.entity.*;
import com.xiaobaibai.service.*;
import com.xiaobaibai.units.SecurityUnit;
import com.xiaobaibai.units.ValidList;
import com.xiaobaibai.vo.CreateOrderItemVo;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xiaobaibai
 * @since 2020-10-16
 */
@Service
public class ProductServiceImpl extends ServiceImpl<ProductDao, Product> implements IProductService {

    @Autowired
    private RestHighLevelClient esClient;

    @Autowired
    private IOrderItemService orderItemService;

    @Override
    @Cacheable(value = {"product"},key = "#root.methodName")
    public List<Product> getAllList() {
        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("product_status",1);
        return this.list(queryWrapper);
    }

    @Override
    @Cacheable(value = {"product"},key = "#root.methodName+'-'+#categoryId")
    public List<Product> getProductByCategory(Integer categoryId) {

        //客服端的必定是底层分类

        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("product_image","id","product_old_price", "product_price",
                "product_unit","productName","product_sales","product_stock");
        queryWrapper.eq("product_status",1);
        queryWrapper.in("category_id",categoryId);

        return this.list(queryWrapper);
    }

    @Override
    @Cacheable(value = {"product"},key = "#root.methodName+'-'+#pageNum")
    public List<Product> getProductPage(int pageNum) {
        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("id","product_image","product_name","product_price","product_unit","product_old_price");
        queryWrapper.eq("product_status",1);
        IPage<Product> page = this.page(new Page<>(pageNum,IndexCommon.pageSize),queryWrapper);
        return page.getRecords();
    }

    @Override//后面做客户端时就来个缓存
    @Cacheable(value = {"product"},key = "#root.methodName+'-'+#font")
    public List<String> associatedWords(String font) {

        SearchRequest searchRequest = new SearchRequest(EsCommon.PRODUCTINDEX);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("productName", font);

        searchSourceBuilder.query(matchQueryBuilder).fetchSource("productName",null);

        searchRequest.source(searchSourceBuilder);

        SearchResponse search = null;
        try {
            search = esClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if(search==null)
            return new ArrayList<>();

        SearchHit[] hits = search.getHits().getHits();

        List<String> list=new ArrayList<>(hits.length);

        for (SearchHit hit : hits) {
            String resultName =(String) hit.getSourceAsMap().get("productName");
            list.add(resultName);
        }

        return list;







//        CompletionSuggestionBuilder suggestion = SuggestBuilders
//                .completionSuggestion("productName.kw")
//                .prefix(font).skipDuplicates(true);//skipDuplicates去除重复
//        SuggestBuilder suggestBuilder = new SuggestBuilder();
//        suggestBuilder.addSuggestion("sugProductName", suggestion);
//
//        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
//        searchSourceBuilder.suggest(suggestBuilder);
//
//        SearchRequest searchRequest=new SearchRequest();
//        searchRequest.source(searchSourceBuilder);
//
//        RestHighLevelClient client=esClient;
//
//        SearchResponse search = null;
//        try {
//            search = client.search(searchRequest, RequestOptions.DEFAULT);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
////        System.out.println(search);//成功
//
////        System.out.println(JSON.toJSONString(search.getSuggest().getSuggestion("sugProductName")));
//
//        Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> sugProductName = search.getSuggest().getSuggestion("sugProductName");
//
//
//        List<String> list=new ArrayList<>();
//
//        for (Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option> entry : sugProductName.getEntries()) {
//            for (Suggest.Suggestion.Entry.Option option : entry) {
//                String suggestText = option.getText().string();
//                list.add(suggestText);
//            }
//        }
//
//        return list;
    }

    @Override
    @Cacheable(value = {"oneProduct"},key = "#root.methodName+'-'+#productId")
    public Product getProductById(Integer productId) {
        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("id",productId);
        queryWrapper.select("id","category_id","product_name","product_image","product_sales","product_stock","product_old_price","product_price","product_unit","product_detail");
        queryWrapper.eq("product_status",1);
        return this.getOne(queryWrapper);
    }

    @Override
    @Cacheable(value = {"oneProduct"},key = "#root.methodName+'-'+#productName")
    public List<ProductEs> searchProduct(String productName) {

        SearchRequest searchRequest = new SearchRequest(EsCommon.PRODUCTINDEX);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQuery=QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.termQuery("productStatus",true));
        boolQuery.must(QueryBuilders.matchQuery("productName",productName));


        searchSourceBuilder.query(boolQuery);

//        searchSourceBuilder.query(
//                QueryBuilders.matchQuery("productName", productName));
//        searchSourceBuilder.query(
//                QueryBuilders.termQuery("productStatus", true));

        searchRequest.source(searchSourceBuilder);

        SearchResponse search = null;
        try {
            search = esClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(JSON.toJSONString(search.getHits()));
        System.out.println(JSON.toJSONString(search.getHits().getHits()));

        List<ProductEs> list=new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            ProductEs productEs = JSON.parseObject(hit.getSourceAsString(), ProductEs.class);
            list.add(productEs);
        }

        return list;
    }

    @Override
    public List<Product> getBargainProduct(Collection<Integer> collection) {
        return this.baseMapper.getProductByList(collection);
    }

    @Override//订单类的,不要缓存
    public List<Product> getProductByOrder(Collection<Integer> collection) {
        return this.baseMapper.getProductByOrder(collection);
    }

    @Override
    public List<Product> getImageById(Collection<Integer> collection) {
        return this.baseMapper.getImageById(collection);
    }

    @Override
    public void returnStock(String orderId) {
        QueryWrapper<OrderItem> q1=new QueryWrapper<>();
        q1.select("product_id","product_count");
        q1.eq("order_id",orderId);
        List<OrderItem> orderItemList = orderItemService.list(q1);
        List<CreateOrderItemVo> list=new ArrayList<>(orderItemList.size());
        orderItemList.forEach(o->{
            CreateOrderItemVo createOrderItemVo=new CreateOrderItemVo();
            createOrderItemVo.setCount(o.getProductCount());
            createOrderItemVo.setProductId(o.getProductId());
            list.add(createOrderItemVo);
        });
        //返还库存
        this.baseMapper.returnStock(list);
    }

}
